//++++++++++++++++++++++++++++++++++++++++++//
// ENBSeries effect file		    //
// visit http://enbdev.com for updates	    //
// Copyright (c) 2007-2013 Boris Vorontsov  //
//++++++++++++++++++++++++++++++++++++++++++//

//++CREDITS++++DO NOT REMOVE!!++++++++++++++++++++++++//
// JawZ: assembling and implementing the GUI feature  //
// & redesigned file layout.			      //
//					 	      //
// Modified by InsomniaJT	                      //
//		      				      //
//++++++++++++++++++++++++++++++++++++++++++++++++++++//

//THIS IS HLSL FILE FORMAT FOR EXECUTING ADDITIONAL
//POST PROCESSING EFFECTS. MAKE THE COPY BEFORE CHANGING IT!


//++++++++++++++++++++++++++++++++
//++++++++++++++++++++++++++++++++

float EVignetteAmount <
string UIName="Vignette Amount";
string UIWidget="Spinner";
float UIMin=0.0;
float UIMax=10.0;
> = {0.6};

float EVignetteCurve <
string UIName="Vignette Curve";
string UIWidget="Spinner";
float UIMin=0.0;
float UIMax=10.0;
> = {1.0};

float EVignetteRadius <
string UIName="Vignette Radius";
string UIWidget="Spinner";
float UIMin=0.0;
float UIMax=10.0;
> = {1.4};

float3 EVignetteColor <
string UIName="Vignette Color";
string UIWidget="Color";
> = {0.0, 0.0, 0.0};

//float	EVignetteAmount=2.6;
//float	EVignetteCurve=1.0;
//float	EVignetteRadius=1.4; //doubled for a little optimization
//float3	EVignetteColor=float3(0.0, 0.0, 0.0); //black


//enable sharpening
#define ESHARPENING

//enable color
#define ECOLORSHIFT

bool ESHARPENINGCOLOR <
string UIName = "Enable Sharpening by Color";
> = {true};

bool EDYNAMICNOISE <
string UIName = "Enable Dynamic Noise";
> = {true};

bool ESTATICNOISE <
string UIName = "Enable Static Noise";
> = {false};

//++++++++++++++++++++++++++++++++
//++++++++++++++++++++++++++++++++



float BlurSamplingRange <
string UIName="Blur Range";
string UIWidget="Spinner";
float UIMin=0.0;
float UIMax=3.0;
> = {0.6};

float ShiftSamplingRange <
string UIName="Color Shift Range";
string UIWidget="Spinner";
float UIMin=0.0;
float UIMax=3.0;
> = {0.25};

float SharpSamplingRange <
string UIName="Sharpening Range";
string UIWidget="Spinner";
float UIMin=0.0;
float UIMax=1.0;
> = {0.5};


float SharpeningAmount <
string UIName="Sharpening Amount";
string UIWidget="Spinner";
float UIMin=0.0;
float UIMax=10.0;
> = {1.25};

float DynamicNoiseAmount <
string UIName="Dynamic Noise Amount";
string UIWidget="Spinner";
float UIMin=0.0;
float UIMax=3.0;
> = {0.125};


float StaticNoiseAmount <
string UIName="Static Noise Amount";
string UIWidget="Spinner";
float UIMin=0.0;
float UIMax=3.0;
> = {0.125};



//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// EXTERNAL PARAMETERS BEGINS HERE, SHOULD NOT BE MODIFIED UNLESS YOU KNOW WHAT YOU ARE DOING!!!
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++



//keyboard controlled temporary variables (in some versions exists in the config file). Press and hold key 1,2,3...8 together with PageUp or PageDown to modify. By default all set to 1.0
float4	tempF1; 	//0,1,2,3
float4	tempF2; 	//5,6,7,8
float4	tempF3; 	//9,0
float4	Timer;		//x=generic timer in range 0..1, period of 16777216 ms (4.6 hours), w=frame time elapsed (in seconds)
float4	ScreenSize;	//x=Width, y=1/Width, z=ScreenScaleY, w=1/ScreenScaleY

//textures
texture2D texColor;
texture2D texDepth;
texture2D texNoise;

sampler2D SamplerColor = sampler_state
{
	Texture   = <texColor>;
	MinFilter = LINEAR;
	MagFilter = LINEAR;
	MipFilter = NONE;//NONE;
	AddressU  = Clamp;
	AddressV  = Clamp;
	SRGBTexture=FALSE;
	MaxMipLevel=0;
	MipMapLodBias=0;
};

sampler2D SamplerDepth = sampler_state
{
	Texture   = <texDepth>;
	MinFilter = POINT;
	MagFilter = POINT;
	MipFilter = NONE;
	AddressU  = Clamp;
	AddressV  = Clamp;
	SRGBTexture=FALSE;
	MaxMipLevel=0;
	MipMapLodBias=0;
};

sampler2D SamplerNoise = sampler_state
{
	Texture   = <texNoise>;
	MinFilter = POINT;
	MagFilter = POINT;
	MipFilter = NONE;//NONE;
	AddressU  = Wrap;
	AddressV  = Wrap;
	SRGBTexture=FALSE;
	MaxMipLevel=0;
	MipMapLodBias=0;
};


struct VS_OUTPUT_POST
{
	float4 vpos  : POSITION;
	float2 txcoord : TEXCOORD0;
};

struct VS_INPUT_POST
{
	float3 pos  : POSITION;
	float2 txcoord : TEXCOORD0;
};



//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

VS_OUTPUT_POST VS_PostProcess(VS_INPUT_POST IN)
{
	VS_OUTPUT_POST OUT;

	float4 pos=float4(IN.pos.x,IN.pos.y,IN.pos.z,1.0);

	OUT.vpos=pos;
	OUT.txcoord.xy=IN.txcoord.xy;

	return OUT;
}


//1 blur
float4 PS_ProcessBlur(VS_OUTPUT_POST IN, float2 vPos : VPOS) : COLOR
{
	float4 res;
	float4 coord=0.0;

	coord.xy=IN.txcoord.xy;
	float4 origcolor;

	coord.w=0.0;

	origcolor=tex2Dlod(SamplerColor, coord);

	float2 offset[16]=
	{
	 float2(1.0, 1.0),
	 float2(-1.0, -1.0),
	 float2(-1.0, 1.0),
	 float2(1.0, -1.0),

	 float2(1.0, 0.0),
	 float2(-1.0, 0.0),
	 float2(0.0, 1.0),
	 float2(0.0, -1.0),

	 float2(1.41, 0.0),
	 float2(-1.41, 0.0),
	 float2(0.0, 1.41),
	 float2(0.0, -1.41),

	 float2(1.41, 1.41),
	 float2(-1.41, -1.41),
	 float2(-1.41, 1.41),
	 float2(1.41, -1.41)
	};
	int i=0;

	float4 tcol=origcolor;
	float2 invscreensize=1.0/ScreenSize.x;
	invscreensize.y=invscreensize.y/ScreenSize.z;
	//for (i=0; i<8; i++) //higher quality
	//for (i=0; i<4; i++)
	for (i=0; i<16; i++)
	{
	 float2 tdir=offset[i].xy;
	 coord.xy=IN.txcoord.xy+tdir.xy*invscreensize*BlurSamplingRange;//*1.0;
	 float4 ct=tex2Dlod(SamplerColor, coord);

	 tcol+=ct;
	}
	//tcol*=0.2; // 1.0/(4+1)
	//tcol*=0.111; // 1.0/(8+1)  //higher quality
	tcol*=0.05882353;

	res.xyz=tcol.xyz;

	res.w=1.0;
	return res;
}


//2 sharp
float4 PS_ProcessSharp(VS_OUTPUT_POST IN, float2 vPos : VPOS) : COLOR
{
	float4 res;
	float4 coord=0.0;

	coord.xy=IN.txcoord.xy;
	float4 origcolor;
	coord.w=0.0;
	origcolor=tex2Dlod(SamplerColor, coord);

	float2 offset[8]=
	{
		float2(1.0, 1.0),
		float2(-1.0, -1.0),
		float2(-1.0, 1.0),
		float2(1.0, -1.0),

		float2(1.41, 0.0),
		float2(-1.41, 0.0),
		float2(0.0, 1.41),
		float2(0.0, -1.41)
	};
	int i=0;

	float4 tcol=origcolor;
	float2 invscreensize=1.0/ScreenSize.x;
	invscreensize.y=invscreensize.y/ScreenSize.z;
	//for (i=0; i<8; i++) //higher quality
	for (i=0; i<4; i++)
	{
	 float2 tdir=offset[i].xy;
	 coord.xy=IN.txcoord.xy+tdir.xy*invscreensize*SharpSamplingRange;//tempF3;//*1.0;
	 float4 ct=tex2Dlod(SamplerColor, coord);

	 tcol+=ct;
	}
	tcol*=0.2; // 1.0/(4+1)
	//tcol*=0.111; // 1.0/(8+1)  //higher quality

//sharp
#ifdef ESHARPENING
    if (ESHARPENINGCOLOR==true) {
	//color
	res=origcolor*(1.0+((origcolor-tcol)*SharpeningAmount));
    } else {
	//non color
	float difffact=dot((origcolor.xyz-tcol.xyz), 0.333);
	res=origcolor*(1.0+difffact*SharpeningAmount);
    }
	//less sharpening for bright pixels
	float rgray=origcolor.z; //blue fit well
	//float rgray=max(origcolor.x, max(origcolor.y, origcolor.z));
	rgray=pow(rgray, 3.0);
	res=lerp(res, origcolor, saturate(rgray));
#endif


//Dynamic noise
    if (EDYNAMICNOISE==true) {
	float origgray=max(res.x, res.y);//dot(res.xyz, 0.333);
	origgray=max(origgray, res.z);
	coord.xy=IN.txcoord.xy*16.0 + frac(Timer.x * 400000.0 + Timer.x);
	float4 cnoi=tex2Dlod(SamplerNoise, coord);
	res=lerp(res, (cnoi.x+0.5)*res, DynamicNoiseAmount*saturate(1.0-origgray*1.8));
    }


//Static noise
    if (ESTATICNOISE==true) {
	float origgray=max(res.x, res.y);//dot(res.xyz, 0.333);
	origgray=max(origgray, res.z);
	coord.xy=IN.txcoord.xy*16.0; // + frac(Timer.x * 400000.0 + Timer.x);
	float4 cnoi=tex2Dlod(SamplerNoise, coord);
	res=lerp(res, (cnoi.x+0.5)*res, StaticNoiseAmount*saturate(1.0-origgray*1.8));
    }

	res.w=1.0;
	return res;

}

//3
float4 PS_ProcessShift(VS_OUTPUT_POST IN, float2 vPos : VPOS) : COLOR
{
	float4 res;
	float4 coord=0.0;

	coord.xy=IN.txcoord.xy;
	float4 origcolor;

	coord.w=0.0;

	origcolor=tex2Dlod(SamplerColor, coord);

	int i=0;

	float4 tcol=origcolor;
	float2 invscreensize=1.0/ScreenSize.x;
	invscreensize.y=invscreensize.y/ScreenSize.z;

	coord.xy=IN.txcoord.xy;
	origcolor=tex2Dlod(SamplerColor, coord);
	res.y=origcolor.y;

	coord.xy=IN.txcoord.xy;
	coord.y-=invscreensize*ShiftSamplingRange;
	origcolor=tex2Dlod(SamplerColor, coord);
	res.x=origcolor.x;

	coord.xy=IN.txcoord.xy;
	coord.y+=invscreensize*ShiftSamplingRange;
	origcolor=tex2Dlod(SamplerColor, coord);
	res.z=origcolor.z;

	res.w=1.0;
	return res;
}


float4 PS_ProcessVignette(VS_OUTPUT_POST IN, float2 vPos : VPOS) : COLOR
{
	float4	res;
	float3	origcolor=tex2D(SamplerColor, IN.txcoord.xy);

	float2	uv=(IN.txcoord.xy-0.5)*EVignetteRadius;
	float	vignette=saturate(dot(uv.xy, uv.xy));
	vignette=pow(vignette, EVignetteCurve);
	res.xyz=lerp(origcolor.xyz, EVignetteColor, vignette*EVignetteAmount);

	res.w=1.0;
	return res;
}


//first must blur							
technique PostProcess
{
	pass P0
	{

		VertexShader = compile vs_3_0 VS_PostProcess();
		PixelShader  = compile ps_3_0 PS_ProcessBlur();

		DitherEnable=FALSE;
		ZEnable=FALSE;
		CullMode=NONE;
		ALPHATESTENABLE=FALSE;
		SEPARATEALPHABLENDENABLE=FALSE;
		AlphaBlendEnable=FALSE;
		StencilEnable=FALSE;
		FogEnable=FALSE;
		SRGBWRITEENABLE=FALSE;
	}
}


//second must sharp
technique PostProcess2
{
	pass P0
	{

		VertexShader = compile vs_3_0 VS_PostProcess();
		PixelShader  = compile ps_3_0 PS_ProcessSharp();

		DitherEnable=FALSE;
		ZEnable=FALSE;
		CullMode=NONE;
		ALPHATESTENABLE=FALSE;
		SEPARATEALPHABLENDENABLE=FALSE;
		AlphaBlendEnable=FALSE;
		StencilEnable=FALSE;
		FogEnable=FALSE;
		SRGBWRITEENABLE=FALSE;
	}
}


#ifdef ECOLORSHIFT
//third must shift
technique PostProcess3
    {
	pass P0
	{
		VertexShader = compile vs_3_0 VS_PostProcess();
		PixelShader  = compile ps_3_0 PS_ProcessShift();

		DitherEnable=FALSE;
		ZEnable=FALSE;
		CullMode=NONE;
		ALPHATESTENABLE=FALSE;
		SEPARATEALPHABLENDENABLE=FALSE;
		AlphaBlendEnable=FALSE;
		StencilEnable=FALSE;
		FogEnable=FALSE;
		SRGBWRITEENABLE=FALSE;
	}
    }
#endif

technique PostProcess4
{
	pass P0
	{

		VertexShader = compile vs_3_0 VS_PostProcess();
		PixelShader  = compile ps_3_0 PS_ProcessVignette();

		DitherEnable=FALSE;
		ZEnable=FALSE;
		CullMode=NONE;
		ALPHATESTENABLE=FALSE;
		SEPARATEALPHABLENDENABLE=FALSE;
		AlphaBlendEnable=FALSE;
		StencilEnable=FALSE;
		FogEnable=FALSE;
		SRGBWRITEENABLE=FALSE;
	}
}